using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using AudioComponent;
using EntitiesAndGameState;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Media;
using Services;
using Utilities.Menu.UIElements;
using WAG.Resources;

namespace WAG.Menu
{
  public class MainMenu : DrawableGameComponent
  {

    enum MenuState
    {
      MainMenu,
      Credits,
      Controls,
      HighScores,
      ModeSelection,
      TrialError
    }

    SpriteBatch sprite_batch;
    InputManager input_manager;

    Matrix screen_transform;
    Box box;
    Texture2D tutorial1, tutorial2, tutorial3, tutorial4, tutorial5, tutorial6, tutorial7, tutorial8, tutorial9, tutorial10, confirm, not_conferm;
    Texture2D audio_on, audio_off;

    int tutorial_page = 0;

    Rectangle top_left, middle_left, mini_top_left, mini_middle_left, mini_bottom_left, mini_top_middle, mini_bottom_middle, confirm_not_confirm_rectangle;

    float alpha = 1.0f, wait_time_to_tap = 0.5f;
    bool increaseAlpha = true, campaign_completed = false;
    MenuState menu_state = MenuState.MainMenu, next_state;

    bool resume_option = false;
    bool show_tutorial;

    public MainMenu(Microsoft.Xna.Framework.Game game)
      : base(game)
    {
      input_manager = new InputManager(game);
      game.Components.Add(input_manager);
      var wakastats = Leaderboard.GetWakaModeStats();

      show_tutorial = wakastats.ShowAlwaysTutorial;
      resume_option = wakastats.LevelScore > 0;

      if (MediaPlayer.State == MediaState.Playing)
      {
        Leaderboard.SaveWakaModeStats(new WakaGarbageModeEntry(
                                                wakastats.ShowAlwaysTutorial,
                                                wakastats.GarbageDestroyed,
                                                wakastats.LevelScore,
                                                wakastats.Level,
                                                wakastats.GreenTrashBinState,
                                                wakastats.YellowTrashBinState,
                                                wakastats.BlueTrashBinState,
                                                wakastats.ManHoleState,
                                                wakastats.EarthLife,
                                                wakastats.TotalGameTime,
                                                wakastats.TimeToNextLevel,
                                                false
                                        ));
        AudioManager.Volume = 0;
      }
      else
      {
        if (wakastats.AudioState)
          AudioManager.Volume = 1;
        else
          AudioManager.Volume = 0;
      }



      this.UpdateOrder = (int)ComponentOrders.TRANSITION + 1;
      this.DrawOrder = (int)ComponentOrders.UI;
    }

    public override void Initialize()
    {
      sprite_batch = Services.GetService(typeof(SpriteBatch)) as SpriteBatch;

      var input_service = Services.GetService(typeof(IInputManager)) as IInputManager;
      input_service.OnTap += on_tap;

      base.Initialize();
    }

    Thread t;
    protected override void LoadContent()
    {
      screen_transform = Matrix.CreateScale(GraphicsDevice.Viewport.Width / SpaceBattleGame.DEFAULT_SCR_WIDTH,
          GraphicsDevice.Viewport.Height / SpaceBattleGame.DEFAULT_SCR_HEIGHT, 1.0f);
      //double_tap = Content.Load<Texture2D>("Menu/double_tap");
      //single_tap = Content.Load<Texture2D>("Menu/single_tap");
      //long_tap = Content.Load<Texture2D>("Menu/long_tap");
      team_logo = Content.Load<Texture2D>("Menu/vst_logo");
      game_title = Content.Load<Texture2D>("Menu/title");
      font_32 = Content.Load<SpriteFont>("Fonts/OCRAExtended30");
      font_16 = Content.Load<SpriteFont>("Fonts/OCRAExtended16");
      font_18 = Content.Load<SpriteFont>("Fonts/OCRAExtended18");
      click = Content.Load<SoundEffect>("Audio/Bip").CreateInstance();
      Playclick = Content.Load<SoundEffect>("Audio/BipStart").CreateInstance();
      error = Content.Load<SoundEffect>("Audio/errors").CreateInstance();

      tutorial1 = Game.Content.Load<Texture2D>(@"Tutorial\Tutorial1");
      tutorial2 = Game.Content.Load<Texture2D>(@"Tutorial\Tutorial2");
      tutorial3 = Game.Content.Load<Texture2D>(@"Tutorial\Tutorial3");
      tutorial4 = Game.Content.Load<Texture2D>(@"Tutorial\Tutorial4");
      tutorial5 = Game.Content.Load<Texture2D>(@"Tutorial\Tutorial5");
      tutorial6 = Game.Content.Load<Texture2D>(@"Tutorial\Tutorial6");
      tutorial7 = Game.Content.Load<Texture2D>(@"Tutorial\Tutorial7");
      tutorial8 = Game.Content.Load<Texture2D>(@"Tutorial\Tutorial8");
      tutorial9 = Game.Content.Load<Texture2D>(@"Tutorial\Tutorial9");
      tutorial10 = Game.Content.Load<Texture2D>(@"Tutorial\Tutorial10");

      audio_on = Game.Content.Load<Texture2D>(@"UIWAG\menu_audio_on");
      audio_off = Game.Content.Load<Texture2D>(@"UIWAG\menu_audio_off");

      confirm = Game.Content.Load<Texture2D>("UI/confirm");
      not_conferm = Game.Content.Load<Texture2D>("UI/not_confirm");

      confirm_not_confirm_rectangle = new Rectangle(795 - confirm.Width, 0, confirm.Width, confirm.Height);

      top_left = new Rectangle(90, 75, 0, 0);
      middle_left = new Rectangle(90, 235, 0, 0);

      mini_top_left = new Rectangle(90, 75, 0, 0);
      mini_middle_left = new Rectangle(90, 175, 0, 0);
      mini_bottom_left = new Rectangle(90, 275, 0, 0);

      mini_top_middle = new Rectangle(400, 125, 0, 0);
      mini_bottom_middle = new Rectangle(400, 225, 0, 0);

      click.Volume = AudioManager.Volume; click.Pan = 0.0f; click.Pitch = 0.0f;
      error.Volume = AudioManager.Volume; error.Pan = 0.0f; error.Pitch = 0.0f;

      box = new Box(new Texture2D[] { Game.Content.Load<Texture2D>("UI/pause_menu_border"),
            Game.Content.Load<Texture2D>("UI/WhitePixel"), Game.Content.Load<Texture2D>("UI/pause_menu_border") },
          new Vector2(445, 70), new Vector2(320, 380), Color.Black, 0.8f);



      if (resume_option)
      {
        buttons = CreateRightAlignedButtons(new string[] { Strings.MainMenu_Resume , Strings.MainMenu_Play , Strings.MainMenu_HighScores, 
                Strings.MainMenu_Credits, Strings.MainMenu_Exit }, 25, 90, 10, 30 + game_title.Width);
      }
      else
      {
        buttons = CreateRightAlignedButtons(new string[] {  Strings.MainMenu_Play , Strings.MainMenu_HighScores,
                Strings.MainMenu_Credits, Strings.MainMenu_Exit }, 50, 90, 10, 30 + game_title.Width);
      }

      game_mode_button = CreateRightAlignedButtons(new string[] { Strings.Tutorial, Strings.Survival, Strings.Back }, 30, 90, 10, 30 + game_title.Width);

      audio = new Button
      {
        CollisionBox = new Rectangle(10, 480 - audio_off.Height - 10, audio_on.Width, audio_on.Height),
        Label = Strings.AudioOn,
        Position = new Vector2(10, 480 - audio_off.Height - 10)
      };



      tutorial_buttons = CreateRightAlignedButtons(new string[] { Strings.Prev, Strings.ExitTutorial, Strings.Next }, 250, 100, 430, 10, 0);
      back = CreateButtons(new string[] { Strings.Back }, 0, 420, 10)[0];
      resume = CreateRightAlignedButtons(new string[] { Strings.ContinueCamp }, 0, 210, 10, 30 + game_title.Width)[0];
      new_campaign = CreateRightAlignedButtons(new string[] { Strings.NewCampaing }, 0, 300, 10, 30 + game_title.Width)[0];
      co_back = CreateRightAlignedButtons(new string[] { Strings.Back }, 0, 390, 10, 30 + game_title.Width)[0];

      t = new Thread(() =>
      {
        // Ship Selection
        Content.Load<Texture2D>("Menu/title_bg");
        Content.Load<Texture2D>("Menu/stat_bg");
        Content.Load<Texture2D>("Menu/buy_box");
        Content.Load<SpriteFont>("Fonts/OCRAExtended32");
        Content.Load<SpriteFont>("Fonts/OCRAExtended18");
        Content.Load<SpriteFont>("Fonts/Orator14");
        Content.Load<SpriteFont>("Fonts/VerySmall");
        Content.Load<Texture2D>("UI/WhitePixel");
        Content.Load<SoundEffect>("Audio/errors");

        // Various Model
        var c = ConfigurationService.GetDefaulConfiguration();

        for (int i = 0; i < c.Ships.Count; i++)
          Content.Load<Model>(c.Ships[i].ModelPath);
      });

      t.Start();

      var sc = Leaderboard.GetScores();

      for (int k = 0; k < sc.Count; k++)
        scores.Add(sc[k]);

      scores = scores.OrderByDescending(s => s.Score).ToList();
      click.Volume = AudioManager.Volume;
      base.LoadContent();
    }

    protected override void Dispose(bool disposing)
    {
      Services.RemoveService(typeof(IInputManager));

      base.Dispose(disposing);
    }

    public override void Update(GameTime gameTime)
    {
      float dt = (float)gameTime.ElapsedGameTime.TotalSeconds;

      wait_time_to_tap -= dt;

      if (input_manager.IsBackButtonPressed() && menu_state == MenuState.MainMenu)
        Game.Exit();

      if (increaseAlpha)
      {
        if (!box.InTransition)
          alpha = MathHelper.Clamp(alpha + dt * 2.0f, 0, 1);
      }
      else
      {
        alpha = MathHelper.Clamp(alpha - dt * 2.0f, 0, 1);
        if (alpha == 0.0f)
        {
          increaseAlpha = true;
          menu_state = next_state;
        }
      }

      if (increaseAlpha) box.Update(dt * 2.0f);

      base.Update(gameTime);
    }

    #region Update Helper

    void OnMainMenuButtonPressed(int tapped_button)
    {
      var tmp = Leaderboard.GetWakaModeStats();
      if (resume_option)
      {
        switch (tapped_button)
        {

          case 0:
            if (!Game.IsTrial())
            {
              if (!(click.State == SoundState.Playing) && AudioManager.AudioState) Playclick.Play();
              ConfigurationService.ChangeConfiguration(Game, ConfigurationService.GetDefaulConfiguration());
              StateManager.SelectSurvivalLevel(Game, t, true,GameMode.Survival);
            }
            else
            {
              if (!Game.IsTrialExpired(tmp.TotalGameTime))
              {
                if (!(click.State == SoundState.Playing) && AudioManager.AudioState) Playclick.Play();
                ConfigurationService.ChangeConfiguration(Game, ConfigurationService.GetDefaulConfiguration());
                StateManager.SelectSurvivalLevel(Game, t, true, GameMode.Survival);
              }
              else
              {
                box.StartTransition(new Vector2(120, 90), new Vector2(560, 280));
                StartTransition(MenuState.TrialError);
                if (AudioManager.AudioState)
                  error.Play();
              }
            }
            break;
          case 1:
            if (!Game.IsTrial())
            {
              if (!(click.State == SoundState.Playing) && AudioManager.AudioState) Playclick.Play();
              //if (!show_tutorial)
              //{

              //  //ConfigurationService.ChangeConfiguration(Game, ConfigurationService.GetDefaulConfiguration());
              //  //StateManager.SelectSurvivalLevel(Game, t, false);
              //}
              //else
              //{
              //game_tutorial = true;
              //tutorial_buttons[1].Label = Strings.Skip;
              //box.StartTransition(new Vector2(45, 50), new Vector2(710, 360));
              //StartTransition(MenuState.Controls);
              menu_state = MenuState.ModeSelection;
              //}
            }
            else
            {
              if (!Game.IsTrialExpired(tmp.TotalGameTime))
              {
                //if (!show_tutorial)
                //{

                //  //ConfigurationService.ChangeConfiguration(Game, ConfigurationService.GetDefaulConfiguration());
                //  //StateManager.SelectSurvivalLevel(Game, t, false);
                //}
                //else
                //{
                //game_tutorial = true;
                //tutorial_buttons[1].Label = Strings.Skip;
                //box.StartTransition(new Vector2(45, 50), new Vector2(710, 360));
                //StartTransition(MenuState.Controls);
                menu_state = MenuState.ModeSelection;
                //}
              }
              else
              {
                box.StartTransition(new Vector2(120, 90), new Vector2(560, 280));
                StartTransition(MenuState.TrialError);
                if (AudioManager.AudioState)
                  error.Play();
              }
            }
            break;

          case 2:
            if (!(click.State == SoundState.Playing) && AudioManager.AudioState) click.Play();
            box.StartTransition(new Vector2(195, 25), new Vector2(410, 380));
            StartTransition(MenuState.HighScores);
            break;
          //case 3:
          //  if (!(click.State == SoundState.Playing) && AudioManager.AudioState) click.Play();
          //  box.StartTransition(new Vector2(45, 60), new Vector2(710, 350));
          //  StartTransition(MenuState.Controls);
          //  break;
          case 3:
            if (!(click.State == SoundState.Playing) && AudioManager.AudioState) click.Play();
            box.StartTransition(new Vector2(120, 70), new Vector2(560, 345));
            StartTransition(MenuState.Credits);
            break;
          case 4:
            if (!(click.State == SoundState.Playing) && AudioManager.AudioState) click.Play();
            Game.Exit();
            break;
          default:
            break;
        }
      }
      else
      {
        switch (tapped_button)
        {

          case 0:
            if (!Game.IsTrial())
            {
              if (!(click.State == SoundState.Playing) && AudioManager.AudioState) Playclick.Play();
              //if (!show_tutorial)
              //{

              //  //ConfigurationService.ChangeConfiguration(Game, ConfigurationService.GetDefaulConfiguration());
              //  //StateManager.SelectSurvivalLevel(Game, t, false);
              //}
              //else
              //{
              //game_tutorial = true;
              //tutorial_buttons[1].Label = Strings.Skip;
              //box.StartTransition(new Vector2(45, 60), new Vector2(710, 350));
              //StartTransition(MenuState.Controls);
              menu_state = MenuState.ModeSelection;
              //}
            }
            else
            {
              if (!Game.IsTrialExpired(tmp.TotalGameTime))
              {
                if (!(click.State == SoundState.Playing) && AudioManager.AudioState) Playclick.Play();
                //if (!show_tutorial)
                //{

                //  //ConfigurationService.ChangeConfiguration(Game, ConfigurationService.GetDefaulConfiguration());
                //  //StateManager.SelectSurvivalLevel(Game, t, false);
                //}
                //else
                //{
                //game_tutorial = true;
                //tutorial_buttons[1].Label = Strings.Skip;
                //box.StartTransition(new Vector2(45, 60), new Vector2(710, 350));
                //StartTransition(MenuState.Controls);
                menu_state = MenuState.ModeSelection;
                //}
              }
              else
              {
                box.StartTransition(new Vector2(120, 90), new Vector2(560, 280));
                StartTransition(MenuState.TrialError);
                if (AudioManager.AudioState)
                  error.Play();
              }
            }
            break;

          case 1:
            if (!(click.State == SoundState.Playing) && AudioManager.AudioState) Playclick.Play();
            box.StartTransition(new Vector2(195, 25), new Vector2(410, 380));
            StartTransition(MenuState.HighScores);
            break;
          //case 2:
          //  if (!(click.State == SoundState.Playing) && AudioManager.AudioState) click.Play();
          //  box.StartTransition(new Vector2(45, 60), new Vector2(710, 350));
          //  StartTransition(MenuState.Controls);
          //  break;
          case 2:
            if (!(click.State == SoundState.Playing) && AudioManager.AudioState) click.Play();
            box.StartTransition(new Vector2(120, 70), new Vector2(560, 345));
            StartTransition(MenuState.Credits);
            break;
          case 3:
            if (!(click.State == SoundState.Playing) && AudioManager.AudioState) click.Play();
            Leaderboard.SaveWakaModeStats(new WakaGarbageModeEntry()
            {
              ShowAlwaysTutorial = tmp.ShowAlwaysTutorial,
              GarbageDestroyed = 0,
              LevelScore = 0,
              Level = 0,
              GreenTrashBinState = 0,
              YellowTrashBinState = 0,
              BlueTrashBinState = 0,
              ManHoleState = 0,
              EarthLife = 0,
              TotalGameTime = tmp.TotalGameTime,
              TimeToNextLevel = 0,
              AudioState = tmp.AudioState
            });
            Game.Exit();
            break;
          default:
            break;
        }
      }
    }

    private void MainMenuUpdate(int tap_x, int tap_y)
    {
      var tapped_button = -1;

      for (int i = 0; i < buttons.Count(); i++)
        if (buttons[i].CollisionBox.Contains(tap_x, tap_y))
        {
          tapped_button = i;
          break;
        }

      OnMainMenuButtonPressed(tapped_button);
    }

    void OnModeSelectionButtonPressed(int tapped_button)
    {
      var tmp = Leaderboard.GetWakaModeStats();
      switch (tapped_button)
      {
        case 0:
          if (!(click.State == SoundState.Playing) && AudioManager.AudioState) Playclick.Play();
          ConfigurationService.ChangeConfiguration(Game, ConfigurationService.GetDefaulConfiguration());
          StateManager.SelectSurvivalLevel(Game, t, false, GameMode.Tutorial);
          break;
        case 1:
          if (!Game.IsTrial())
          {
            if (!(click.State == SoundState.Playing) && AudioManager.AudioState) Playclick.Play();
            ConfigurationService.ChangeConfiguration(Game, ConfigurationService.GetDefaulConfiguration());
            StateManager.SelectSurvivalLevel(Game, t, false, GameMode.Survival);
          }
          else
          {
            if (!Game.IsTrialExpired(tmp.TotalGameTime))
            {
              ConfigurationService.ChangeConfiguration(Game, ConfigurationService.GetDefaulConfiguration());
              StateManager.SelectSurvivalLevel(Game, t, false, GameMode.Survival);
            }
            else
            {
              box.StartTransition(new Vector2(120, 90), new Vector2(560, 280));
              StartTransition(MenuState.TrialError);
              if (AudioManager.AudioState)
                error.Play();
            }
          }
          break;
        case 2:
          menu_state = MenuState.MainMenu;
          break;
        default:
          break;
      }
    }

    private void ModeSelectionUpdate(int tap_x, int tap_y)
    {
      var tapped_button = -1;

      for (int i = 0; i < game_mode_button.Count(); i++)
        if (game_mode_button[i].CollisionBox.Contains(tap_x, tap_y))
        {
          tapped_button = i;
          //if (!(click.State == SoundState.Playing)) click.Play();
          break;
        }

      OnModeSelectionButtonPressed(tapped_button);
    }

    #endregion

    public override void Draw(GameTime gameTime)
    {
      sprite_batch.Begin(SpriteSortMode.Deferred, null, null, null, null, null, screen_transform);

      //sprite_batch.Draw(bg, new Rectangle(0, 0, 480, 800), Color.White);

      sprite_batch.Draw(game_title, new Vector2(30, 50),
          Color.White);

      box.Draw(sprite_batch);

      //sprite_batch.Draw(audio_bar, audio_rect_bar, Color.White);

      if (AudioManager.AudioState)
        sprite_batch.Draw(audio_on, audio.CollisionBox, Color.White);
      else
        sprite_batch.Draw(audio_off, audio.CollisionBox, Color.White);

      switch (menu_state)
      {
        case MenuState.MainMenu:
          DrawMenu();
          break;
        case MenuState.Credits:
          DrawCredits();
          break;
        case MenuState.Controls:
          DrawControls();
          break;
        case MenuState.HighScores:
          DrawHighScores();
          break;
        case MenuState.ModeSelection:
          DrawSelectMode();
          break;
        case MenuState.TrialError:
          DrawTrial();
          break;
      }

      sprite_batch.End();

      base.Draw(gameTime);
    }

    #region Private Methods

    #region OnTap & CreateButtons

    Button back, resume, new_campaign;

    Button[] tutorial_buttons;

    SoundEffectInstance click, Playclick;
    private void on_tap(Vector2 tap_position)
    {
      if (wait_time_to_tap <= 0.0f)
      {
        int tap_x = (int)(tap_position.X / screen_transform.M11), tap_y = (int)(tap_position.Y / screen_transform.M22);

        if (audio.CollisionBox.Contains(tap_x, tap_y))
        {
          if (MediaPlayer.State == MediaState.Playing)
            return;

          if (AudioManager.AudioState) AudioManager.Volume = 0;
          else AudioManager.Volume = 1;

          click.Volume = AudioManager.Volume;

          var tmp = Leaderboard.GetWakaModeStats();

          Leaderboard.SaveWakaModeStats(new WakaGarbageModeEntry(
                                          tmp.ShowAlwaysTutorial,
                                          tmp.GarbageDestroyed,
                                          tmp.LevelScore,
                                          tmp.Level,
                                          tmp.GreenTrashBinState,
                                          tmp.YellowTrashBinState,
                                          tmp.BlueTrashBinState,
                                          tmp.ManHoleState,
                                          tmp.EarthLife,
                                          tmp.TotalGameTime,
                                          tmp.TimeToNextLevel,
                                          AudioManager.AudioState
                                          ));

          if (!(click.State == SoundState.Playing) && AudioManager.AudioState) click.Play();
        }

        switch (menu_state)
        {
          case MenuState.MainMenu:
            MainMenuUpdate(tap_x, tap_y);
            break;
          case MenuState.ModeSelection:
            ModeSelectionUpdate(tap_x, tap_y);
            break;
          default:
            var x = (int)tap_position.X;
            var y = (int)tap_position.Y;
            if (confirm_not_confirm_rectangle.Contains(x, y))
            {
              if (!(click.State == SoundState.Playing) && AudioManager.AudioState) click.Play();
              var tmp = Leaderboard.GetWakaModeStats();
              Leaderboard.SaveWakaModeStats(new WakaGarbageModeEntry(
                                                  !tmp.ShowAlwaysTutorial,
                                                    tmp.GarbageDestroyed,
                                                    tmp.LevelScore,
                                                    tmp.Level,
                                                    tmp.GreenTrashBinState,
                                                    tmp.YellowTrashBinState,
                                                    tmp.BlueTrashBinState,
                                                    tmp.ManHoleState,
                                                    tmp.EarthLife,
                                                    tmp.TotalGameTime,
                                                    tmp.TimeToNextLevel,
                                                    tmp.AudioState
                                                  ));
              show_tutorial = !show_tutorial;
            }
            else
            {
              for (int i = 0; i < tutorial_buttons.Count(); i++)
              {
                if (tutorial_buttons[i].CollisionBox.Contains(x, y))
                {
                  if (i == 0 && (tutorial_page > 0))
                  {
                    if (!(click.State == SoundState.Playing) && AudioManager.AudioState) click.Play();
                    tutorial_page--;
                  }
                  else if (i == 1)
                  {
                    if (!(click.State == SoundState.Playing) && AudioManager.AudioState) click.Play();

                    box.StartTransition(new Vector2(445, 70), new Vector2(320, 380));
                    StartTransition(MenuState.MainMenu);

                    tutorial_page = 0;
                  }
                  else if (i == 2 && (tutorial_page < 4))
                  {
                    if (!(click.State == SoundState.Playing) && AudioManager.AudioState) click.Play();
                    tutorial_page++;
                  }
                }
              }
              if (back.CollisionBox.Contains(tap_x, tap_y) && !(menu_state == MenuState.Controls) || input_manager.IsBackButtonPressed())
              {
                if (!(click.State == SoundState.Playing) && AudioManager.AudioState) click.Play();
                box.StartTransition(new Vector2(445, 70), new Vector2(320, 380));
                StartTransition(MenuState.MainMenu);
              }
            }
            break;
        }
      }
    }

    private Button[] CreateButtons(string[] labels, int offset, int starting_y, int padding)
    {
      int w = GraphicsDevice.Viewport.Width;
      int h = GraphicsDevice.Viewport.Height;
      Button[] bs = new Button[labels.Count()];

      for (int i = 0; i < bs.Count(); i++)
      {
        Vector2 label_measure = font_32.MeasureString(labels[i]);
        int x = (int)(w / 2 - label_measure.X / 2.0f);
        int y = starting_y + i * (offset + (int)label_measure.Y);
        bs[i] = new Button()
        {
          CollisionBox = new Rectangle(x - padding, y - padding, (int)label_measure.X + padding * 2, (int)label_measure.Y + padding * 2),
          Label = labels[i],
          Position = new Vector2(x, y)
        };
      }

      return bs;
    }

    private enum ButtonAligment
    {
      Left,
      Right
    }

    private Button[] CreateRightAlignedButtons(string[] labels, int offset, int starting_y, int padding, int align_val)
    {
      int w = GraphicsDevice.Viewport.Width;
      int h = GraphicsDevice.Viewport.Height;
      Button[] bs = new Button[labels.Count()];

      for (int i = 0; i < bs.Count(); i++)
      {
        Vector2 label_measure = font_32.MeasureString(labels[i]);
        int x = (int)((w + align_val) / 2.0f - label_measure.X / 2.0f);
        int y = starting_y + i * (offset + (int)label_measure.Y);
        bs[i] = new Button()
        {
          CollisionBox = new Rectangle(x - padding, y - padding, (int)label_measure.X + padding * 2, (int)label_measure.Y + padding * 2),
          Label = labels[i],
          Position = new Vector2(x, y)
        };
      }

      return bs;
    }

    private Button[] CreateRightAlignedButtons(string[] labels, int offset, int starting_x, int starting_y, int padding, int align_val)
    {
      int w = GraphicsDevice.Viewport.Width;
      int h = GraphicsDevice.Viewport.Height;
      Button[] bs = new Button[labels.Count()];

      for (int i = 0; i < bs.Count(); i++)
      {
        Vector2 label_measure = font_32.MeasureString(labels[i]);
        var x = starting_x + i * offset;
        //int x = (int)((w + align_val) / 2.0f - label_measure.X / 2.0f);
        int y = starting_y;
        bs[i] = new Button()
        {
          CollisionBox = new Rectangle(x, y, (int)label_measure.X, (int)label_measure.Y),
          Label = labels[i],
          Position = new Vector2(x, y)
        };
      }

      return bs;
    }


    #endregion

    private void StartTransition(MenuState next)
    {
      next_state = next;
      increaseAlpha = false;
    }

    #region Draw Helper

    #region HighScores

    List<LeaderboardEntry> scores = new List<LeaderboardEntry>();
    private void DrawHighScores()
    {
      var title = Strings.MainMenu_HighScores;
      sprite_batch.DrawString(font_32, title, new Vector2(GraphicsDevice.Viewport.Width / 2.0f - font_32.MeasureString(title).X / 2.0f,
          40) + Vector2.One * 2.5f, Color.Black * alpha);
      sprite_batch.DrawString(font_32, title, new Vector2(GraphicsDevice.Viewport.Width / 2.0f - font_32.MeasureString(title).X / 2.0f,
          40), Color.White * alpha);

      int i = 0;

      for (int y = 0; y < scores.Count; y++)
      {
        var s = scores[y];
        sprite_batch.DrawString(font_16, s.Name, new Vector2(250, 130 + 40 * i), Color.White * alpha);
        sprite_batch.DrawString(font_16, s.Score.ToString(), new Vector2(370, 130 + 40 * i), Color.White * alpha);
        sprite_batch.DrawString(font_16, s.Date, new Vector2(450, 130 + 40 * i), Color.White * alpha);
        i++;
      }

      if (i == 0)
      {
        sprite_batch.DrawString(font_16, "--", new Vector2(Game.GraphicsDevice.Viewport.Width / 2 - 10.0f, 150), Color.White * alpha);
      }

      sprite_batch.DrawString(font_32, back.Label, back.Position + Vector2.One * 2.5f, Color.Black * alpha);
      sprite_batch.DrawString(font_32, back.Label, back.Position, Color.White * alpha);
    }

    #endregion

    #region Credits
    Texture2D
      //single_tap, 
      //double_tap, 
      //long_tap, 
        team_logo;
    private void DrawCredits()
    {
      sprite_batch.Draw(team_logo, new Rectangle(155, (int)(GraphicsDevice.Viewport.Height / 2.0f - 39), 200, 78),
          Color.White * alpha);

      //sprite_batch.DrawString(font_16, "Lead Developer:", new Vector2(120, 380), Color.White * alpha);
      sprite_batch.DrawString(font_18, "Antonio De Faveri", new Vector2(390, 80), Color.White * alpha);
      sprite_batch.DrawString(font_18, "Enrico Steffinlongo", new Vector2(390, 110), Color.White * alpha);
      sprite_batch.DrawString(font_18, "Francesco Boscariol", new Vector2(390, 140), Color.White * alpha);
      sprite_batch.DrawString(font_18, "Mario Soprano", new Vector2(390, 170), Color.White * alpha);
      //sprite_batch.DrawString(font_18, "Enrico Steffinlongo", new Vector2(390, 200), Color.White * alpha);
      //sprite_batch.DrawString(font_16, Strings.Thanks, new Vector2(375, 230), Color.White * alpha);
      //sprite_batch.DrawString(font_18, "Luca Cosmo", new Vector2(390, 260), Color.White * alpha);
      //sprite_batch.DrawString(font_18, "Davide Luzzu", new Vector2(390, 290), Color.White * alpha);
      //sprite_batch.DrawString(font_18, "Francesco Usai", new Vector2(390, 320), Color.White * alpha);
      //sprite_batch.DrawString(font_18, "Edoardo Micheli", new Vector2(390, 350), Color.White * alpha);

      sprite_batch.DrawString(font_32, back.Label, back.Position + Vector2.One * 2.5f, Color.Black * alpha);
      sprite_batch.DrawString(font_32, back.Label, back.Position, Color.White * alpha);
    }

    #endregion

    #region Trial
    private void DrawTrial()
    {
      sprite_batch.Draw(team_logo, new Rectangle(155, (int)(GraphicsDevice.Viewport.Height / 2.0f - 39), 200, 78),
          Color.White * alpha);

      sprite_batch.DrawString(font_18, Strings.Trial_Msg.Replace("\\n", "\n"), new Vector2(390, 210), Color.White * alpha);
      sprite_batch.DrawString(font_18, Strings.Trial_Msg.Replace("\\n", "\n"), new Vector2(391, 210), Color.White * alpha);

      sprite_batch.DrawString(font_32, back.Label, back.Position + Vector2.One * 2.5f, Color.Black * alpha);
      sprite_batch.DrawString(font_32, back.Label, back.Position, Color.White * alpha);
    }
    #endregion
    #region Controls

    private void DrawControls()
    {
      if (show_tutorial)
        sprite_batch.Draw(confirm, confirm_not_confirm_rectangle, Color.White * alpha);
      else
        sprite_batch.Draw(not_conferm, confirm_not_confirm_rectangle, Color.White * alpha);


      sprite_batch.DrawString(font_16, Strings.Tutorial_Option.Replace("\\n", "\n"),
                 new Vector2(confirm_not_confirm_rectangle.X - (Strings.Tutorial_Option.Replace("\\n", "\n").Count() * 13), confirm_not_confirm_rectangle.Y + 10), Color.DarkGray * alpha);
      sprite_batch.DrawString(font_16, Strings.Tutorial_Option.Replace("\\n", "\n"),
          new Vector2(confirm_not_confirm_rectangle.X - Strings.Tutorial_Option.Replace("\\n", "\n").Count() * 13 - 1, confirm_not_confirm_rectangle.Y + 10), Color.White * alpha);

      switch (tutorial_page)
      {
        case 0:

          sprite_batch.DrawString(font_16, Strings.TitleTutorial5 + " \n" + Strings.Tutorial9.Replace("\\n", "\n"),
              new Vector2(421, top_left.Y), Color.DarkGray * alpha);
          sprite_batch.DrawString(font_16, Strings.TitleTutorial5 + " \n" + Strings.Tutorial9.Replace("\\n", "\n"),
              new Vector2(420, top_left.Y), Color.White * alpha);

          sprite_batch.DrawString(font_16, Strings.Tutorial10.Replace("\\n", "\n"),
              new Vector2(421, middle_left.Y), Color.DarkGray * alpha);
          sprite_batch.DrawString(font_16, Strings.Tutorial10.Replace("\\n", "\n"),
              new Vector2(420, middle_left.Y), Color.White * alpha);


          top_left.Width = tutorial9.Width;
          top_left.Height = tutorial9.Height;
          sprite_batch.Draw(tutorial9, top_left, Color.White * alpha);

          middle_left.Width = tutorial10.Width;
          middle_left.Height = tutorial10.Height;
          sprite_batch.Draw(tutorial10, middle_left, Color.White * alpha);

          for (int i = 1; i < tutorial_buttons.Count(); i++)
          {
            sprite_batch.DrawString(font_32, tutorial_buttons[i].Label, tutorial_buttons[i].Position + Vector2.One * 2.5f, Color.Black * alpha);
            sprite_batch.DrawString(font_32, tutorial_buttons[i].Label, tutorial_buttons[i].Position, Color.White * alpha);
          }

          break;
        case 1:

          sprite_batch.DrawString(font_16, Strings.TitleTutorial1 + " \n" + Strings.Tutorial1.Replace("\\n", "\n"),
              new Vector2(421, top_left.Y), Color.DarkGray * alpha);
          sprite_batch.DrawString(font_16, Strings.TitleTutorial1 + " \n" + Strings.Tutorial1.Replace("\\n", "\n"),
              new Vector2(420, top_left.Y), Color.White * alpha);

          sprite_batch.DrawString(font_16, Strings.Tutorial2.Replace("\\n", "\n"),
              new Vector2(421, middle_left.Y), Color.DarkGray * alpha);
          sprite_batch.DrawString(font_16, Strings.Tutorial2.Replace("\\n", "\n"),
              new Vector2(420, middle_left.Y), Color.White * alpha);


          top_left.Width = tutorial1.Width;
          top_left.Height = tutorial1.Height;
          sprite_batch.Draw(tutorial1, top_left, Color.White * alpha);

          middle_left.Width = tutorial2.Width;
          middle_left.Height = tutorial2.Height;
          sprite_batch.Draw(tutorial2, middle_left, Color.White * alpha);

          for (int i = 0; i < tutorial_buttons.Count(); i++)
          {
            sprite_batch.DrawString(font_32, tutorial_buttons[i].Label, tutorial_buttons[i].Position + Vector2.One * 2.5f, Color.Black * alpha);
            sprite_batch.DrawString(font_32, tutorial_buttons[i].Label, tutorial_buttons[i].Position, Color.White * alpha);
          }

          break;
        case 2:

          sprite_batch.DrawString(font_16, Strings.TitleTutorial2 + " \n" + Strings.Tutorial3.Replace("\\n", "\n"),
              new Vector2(421, top_left.Y), Color.DarkGray * alpha);
          sprite_batch.DrawString(font_16, Strings.TitleTutorial2 + " \n" + Strings.Tutorial3.Replace("\\n", "\n"),
              new Vector2(420, top_left.Y), Color.White * alpha);

          sprite_batch.DrawString(font_16, Strings.Tutorial4.Replace("\\n", "\n"),
              new Vector2(421, middle_left.Y), Color.DarkGray * alpha);
          sprite_batch.DrawString(font_16, Strings.Tutorial4.Replace("\\n", "\n"),
              new Vector2(420, middle_left.Y), Color.White * alpha);


          top_left.Width = tutorial3.Width;
          top_left.Height = tutorial3.Height;
          sprite_batch.Draw(tutorial3, top_left, Color.White * alpha);

          middle_left.Width = tutorial4.Width;
          middle_left.Height = tutorial4.Height;
          sprite_batch.Draw(tutorial4, middle_left, Color.White * alpha);

          for (int i = 0; i < tutorial_buttons.Count(); i++)
          {
            sprite_batch.DrawString(font_32, tutorial_buttons[i].Label, tutorial_buttons[i].Position + Vector2.One * 2.5f, Color.Black * alpha);
            sprite_batch.DrawString(font_32, tutorial_buttons[i].Label, tutorial_buttons[i].Position, Color.White * alpha);
          }

          break;
        case 3:

          sprite_batch.DrawString(font_16, Strings.TitleTutorial3 + " \n" + Strings.Tutorial5.Replace("\\n", "\n"),
              new Vector2(421, top_left.Y), Color.DarkGray * alpha);
          sprite_batch.DrawString(font_16, Strings.TitleTutorial3 + " \n" + Strings.Tutorial5.Replace("\\n", "\n"),
              new Vector2(420, top_left.Y), Color.White * alpha);

          sprite_batch.DrawString(font_16, Strings.Tutorial6.Replace("\\n", "\n"),
              new Vector2(421, middle_left.Y), Color.DarkGray * alpha);
          sprite_batch.DrawString(font_16, Strings.Tutorial6.Replace("\\n", "\n"),
              new Vector2(420, middle_left.Y), Color.White * alpha);


          top_left.Width = tutorial5.Width;
          top_left.Height = tutorial5.Height;
          sprite_batch.Draw(tutorial5, top_left, Color.White * alpha);

          middle_left.Width = tutorial6.Width;
          middle_left.Height = tutorial6.Height;
          sprite_batch.Draw(tutorial6, middle_left, Color.White * alpha);


          for (int i = 0; i < tutorial_buttons.Count(); i++)
          {
            sprite_batch.DrawString(font_32, tutorial_buttons[i].Label, tutorial_buttons[i].Position + Vector2.One * 2.5f, Color.Black * alpha);
            sprite_batch.DrawString(font_32, tutorial_buttons[i].Label, tutorial_buttons[i].Position, Color.White * alpha);
          }
          tutorial_buttons[1].Label = tutorial_buttons[1].Label; ;

          break;
        case 4:

          sprite_batch.DrawString(font_16, Strings.TitleTutorial4 + " \n" + Strings.Tutorial7.Replace("\\n", "\n"),
              new Vector2(421, top_left.Y), Color.DarkGray * alpha);
          sprite_batch.DrawString(font_16, Strings.TitleTutorial4 + " \n" + Strings.Tutorial7.Replace("\\n", "\n"),
              new Vector2(420, top_left.Y), Color.White * alpha);

          sprite_batch.DrawString(font_16, Strings.Tutorial8.Replace("\\n", "\n"),
              new Vector2(421, middle_left.Y), Color.DarkGray * alpha);
          sprite_batch.DrawString(font_16, Strings.Tutorial8.Replace("\\n", "\n"),
              new Vector2(420, middle_left.Y), Color.White * alpha);


          top_left.Width = tutorial7.Width;
          top_left.Height = tutorial7.Height;
          sprite_batch.Draw(tutorial7, top_left, Color.White * alpha);

          middle_left.Width = tutorial8.Width;
          middle_left.Height = tutorial8.Height;
          sprite_batch.Draw(tutorial8, middle_left, Color.White * alpha);

          tutorial_buttons[1].Label = Strings.ExitTutorial;

          for (int i = 0; i < tutorial_buttons.Count() - 1; i++)
          {
            sprite_batch.DrawString(font_32, tutorial_buttons[i].Label, tutorial_buttons[i].Position + Vector2.One * 2.5f, Color.Black * alpha);
            sprite_batch.DrawString(font_32, tutorial_buttons[i].Label, tutorial_buttons[i].Position, Color.White * alpha);
          }
          tutorial_buttons[1].Label = tutorial_buttons[1].Label;

          break;
      }






    }

    #endregion

    #region Menu

    Button[] buttons;
    Button[] game_mode_button;
    Button audio;
    SpriteFont font_32, font_16;
    Texture2D game_title;

    void DrawMenu()
    {

      for (int i = 0; i < buttons.Count(); i++)
      {
        sprite_batch.DrawString(font_32, buttons[i].Label, buttons[i].Position + Vector2.One * 2.5f, Color.Black * alpha);
        sprite_batch.DrawString(font_32, buttons[i].Label, buttons[i].Position, Color.White * alpha);
      }

    }
    #endregion

    #region SelectGameMode

    private SoundEffectInstance error;
    private SpriteFont font_18;
    private Button co_back;

    void DrawSelectMode()
    {
      var a = 1.0f;
      for (int i = 0; i < game_mode_button.Count(); i++)
      {
        sprite_batch.DrawString(font_32, game_mode_button[i].Label, game_mode_button[i].Position + Vector2.One * 2.5f, Color.Black * (Math.Min(alpha, a)));
        sprite_batch.DrawString(font_32, game_mode_button[i].Label, game_mode_button[i].Position, Color.White * (Math.Min(alpha, a)));
      }

    }

    void DrawCampaignOption()
    {
      if (!campaign_completed)
      {
        sprite_batch.DrawString(font_32, resume.Label, resume.Position + Vector2.One * 2.5f, Color.Black * alpha);
        sprite_batch.DrawString(font_32, resume.Label, resume.Position, Color.White * alpha);
      }

      sprite_batch.DrawString(font_32, new_campaign.Label, new_campaign.Position + Vector2.One * 2.5f, Color.Black * alpha);
      sprite_batch.DrawString(font_32, new_campaign.Label, new_campaign.Position, Color.White * alpha);

      sprite_batch.DrawString(font_32, co_back.Label, co_back.Position + Vector2.One * 2.5f, Color.Black * alpha);
      sprite_batch.DrawString(font_32, co_back.Label, co_back.Position, Color.White * alpha);
    }

    #endregion

    #endregion

    #endregion

    ContentManager Content { get { return Game.Content; } }
    GameServiceContainer Services { get { return Game.Services; } }
    GameComponentCollection Components { get { return Game.Components; } }
  }
}
